package projorientado.ocr.vfeature.impl.comparator;

import projorientado.image.ImageComparator;
import projorientado.image.ImageLayerData;

public class BComparator implements ImageComparator {

    public static final BComparator instance = new BComparator();
    
    public float compareImages(ImageLayerData image1, ImageLayerData image2) {
        
        float i1sx = 1f, i1sy = 1f;
        float i2sx = 1f, i2sy = 1f;
        
        int width = Math.min(image1.getWidth(),image2.getWidth());
        int height = Math.min(image1.getHeight(),image2.getHeight());
        
        if(image1.getWidth() > image2.getWidth()) {
            i1sx = (float)image2.getWidth()/(float)image1.getWidth();
        } else if(image2.getWidth() > image1.getWidth()) {
            i2sx = (float)image1.getWidth()/(float)image2.getWidth();
        }
        
        if(image1.getHeight() > image2.getHeight()) {
            i1sy = (float)image2.getHeight()/(float)image1.getHeight();
        } else if(image2.getWidth() > image1.getHeight()) {
            i2sx = (float)image1.getHeight()/(float)image2.getHeight();
        }
        
        float ret = 0;
        for(int x = 0; x < width; x++) {
            for(int y = 0; y < height; y++) {
                float v = getPointCost(image1,image2,x,y,width,height,i1sx, i1sy, i2sx, i2sy);
                ret += v*v;
            }
        }
        
        return (100*ret)/(width*height);
        
    }
    
    public static float getPointCost(ImageLayerData image1, ImageLayerData image2, 
            int px, int py, int w, int h,
            float i1sx, float i1sy, float i2sx, float i2sy) {  
        
        float p1 = getSafePoint(image1,px,py,w,h,i1sx,i1sy);
        float p2 = getSafePoint(image2,px,py,w,h,i2sx,i2sy);
        
        float diff = Math.abs(p1-p2);
        
        if(diff > 0.8f) {
        
            float n1 = 0,n2 = 0;
            for(int x = -1; x <= 1; x++) {
                for(int y = -1; y <= 1; y++) {
                    double p = (2-Math.sqrt(x*x + y*y))/2;
                    n1 += getSafePoint(image1,x+px,y+py,w,h,i1sx,i1sy)*p;
                    n2 += getSafePoint(image2,x+px,y+py,w,h,i2sx,i2sy)*p;
                }
            }
            return Math.abs(n1 - n2)/9;
        
        }
        
        return diff;
        
    }
    
    public static float getSafePoint(ImageLayerData img, int x, int y,
            int w, int h,
            float sx, float sy) {
        if(x >= 0 && x < w && y >= 0 && y < h) {
            return img.getScaledPoint(x, y, sy, sy);
        }
        return 1f;
    }

}
